using JigLibX.Geometry;
using Microsoft.Xna.Framework;

namespace SolarWinds.Shapes
{
    /// <summary>
    /// A shape is the geometric reprenstation of a scene node.
    /// It has not transformations assigned to it. 
    /// </summary>
    public abstract class Shape : DrawableGameComponent
    {
        #region Transformations

        private bool mWorldDirty;

        private Vector3 mPosition = Vector3.Zero;
        public Vector3 Position
        {
            get { return mPosition; }
            set
            {
                if (mPosition != value)
                {
                    mPosition = value;

                    mWorldDirty |= true;
                }
            }
        }

        private Quaternion mRotation = Quaternion.Identity;
        public Quaternion Rotation
        {
            get { return mRotation; }
            set
            {
                if (mRotation != value)
                {
                    mRotation = value;

                    mWorldDirty |= true;
                }
            }
        }

        private Vector3 mScale = Vector3.One;
        public Vector3 Scale
        {
            get { return mScale; }
            set
            {
                if (mScale != value)
                {
                    mScale = value;

                    mWorldDirty |= true;
                }
            }
        }

        private Matrix mWorld;
        public Matrix World
        {
            get
            {
                if (mWorldDirty)
                {
                    mWorld = Matrix.CreateScale(mScale) *
                        Matrix.CreateFromQuaternion(mRotation) *
                        Matrix.CreateTranslation(mPosition);
                }
                return mWorld;
            }
        }

        #endregion

        #region Bounds

        protected BoundingSphere mBoundingSphere;
        public BoundingSphere BoundingSphere
        {
            get { return mBoundingSphere; }
        }

        public bool BoundingSphereVisible { get; set; }
        
        protected BoundingBox mBoundingBox;
        public BoundingBox BoundingBox
        {
            get { return mBoundingBox; }
        }

        public bool BoundingBoxVisible { get; set; }
        
        #endregion

        #region Camera

        public Matrix View
        {
            get { return SolarWindsGame.Camera.View; }
        }

        public Matrix Projection
        {
            get { return SolarWindsGame.Camera.Projection; }
        }

        #endregion

        protected Shape(Game game) : base(game)
        {
        }

        protected override void LoadContent()
        {
            mBoundingBox = UpdateBoundingBox();
            mBoundingSphere = UpdateBoundingSphere();   
        }

        protected abstract BoundingSphere UpdateBoundingSphere();
        protected abstract BoundingBox UpdateBoundingBox();

        protected override void UnloadContent()
        {
        }
    }
}